<template>
  <div class="table-column-group">
    <div class="table-column-item" v-for="(obj, i) in arr" :key="i">
      <i
        class="icon iconfont"
        draggable="true"
        @dragstart="dragStart($event, i)"
        @dragover="dragOver($event, i)"
        @drop="drop($event, i)"
        @dragend="dragEnd($event, i)"
      >
        &#xe647;
      </i>
      <!-- 字段类型 -->
      <el-select
        class="value"
        :model-value="obj.type"
        @change="change('type', $event, i)"
        placeholder="字段类型"
      >
        <el-option
          v-for="item in typeArr"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>
      <el-input
        class="value"
        :model-value="obj.title"
        @input="change('title', $event, i)"
        placeholder="字段名"
      />
      <!-- 更多配置 -->
      <div v-if="moreConfig">
        <el-input
          class="value"
          :model-value="obj.key"
          @input="change('key', $event, i)"
          placeholder="字段key"
        />
        <el-input
          class="value"
          :model-value="obj.validateFn"
          @input="change('validateFn', $event, i)"
          placeholder="数值校验函数"
          :disabled="obj.type !== 'NumberInput'"
        />
        <el-switch
          :model-value="obj.required"
          @change="change('required', $event as boolean, i)"
          active-text="必填"
          inactive-text="非必填"
          :disabled="obj.type == 'string' || obj.type == 'image'"
        />
      </div>
      <!-- 更多配置 -->
      <el-button
        type="danger"
        @click="remove(i)"
        text
        circle
        style="cursor: pointer; margin-left: 30px"
      >
        <i class="icon iconfont" style="cursor: pointer">&#xe718;</i>
      </el-button>
    </div>
    <div class="btn-group">
      <el-button type="primary" text @click="add">添加选项</el-button>
      <el-button v-if="!moreConfig" text @click="openMoreConfig">更多配置</el-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ElMessage } from 'element-plus'
import { inputTypeArr, initInputConfig } from '../utils'
const emits = defineEmits(['open', 'change', 'update:modelValue'])
const props = defineProps({
  modelValue: {
    type: Array as () => any[],
    default() {
      return []
    }
  },
  moreConfig: {
    type: Boolean,
    default() {
      return false
    }
  }
})
const typeArr = ref<
  {
    label: string
    value: string
  }[]
>(inputTypeArr)
const arr = ref<
  {
    key: string
    title: string
    required: boolean
    type: string
    fmtFn: string
    validateFn: string
  }[]
>([])
const dragIndex = ref<number | null>(null)
const hoverIndex = ref<number | null>(null)
const dragStart = (e: DragEvent, index: number) => {
  // console.log('dragStart', e, index)
  dragIndex.value = index
}
const dragOver = (e: DragEvent, index: number) => {
  e.preventDefault()
  // console.log('dragOver', e, index, dragIndex.value)
  hoverIndex.value = index
  if (dragIndex.value != null && dragIndex.value != index) {
    const move = arr.value[dragIndex.value]
    arr.value.splice(dragIndex.value, 1)
    arr.value.splice(index, 0, move)
    dragIndex.value = index
    arr.value = [...arr.value]
  }
}
const drop = (e: DragEvent, index: number) => {
  e.preventDefault()
  // console.log('drop', e, index, dragIndex.value)
  if (dragIndex.value != null && dragIndex.value != index) {
    const move = arr.value[dragIndex.value]
    arr.value.splice(dragIndex.value, 1)
    arr.value.splice(index, 0, move)
    dragIndex.value = index
    arr.value = [...arr.value]
  }
}
const dragEnd = (e: DragEvent, index: number) => {
  // console.log('dragEnd', e, index)
  // 这里可以添加拖拽结束后的处理逻辑，比如更新后端数据等
  setValue()
}
// 新增
const add = () => {
  const key = 'val' + Number(arr.value.length + 1)
  arr.value.push(initInputConfig(key))
}
// 校验
const verify = (index: number) => {
  const obj = arr.value[index]
  const repeat = arr.value.filter((el, i) => i != index).find((el) => el.key === obj.key)
  if (repeat) {
    ElMessage.error('输入字段key重复')
    return false
  } else {
    return true
  }
}
// 改变
const change = (key: string, value: string | boolean | string, index: number) => {
  if (!verify(index)) return
  arr.value = arr.value.map((el: any, i: number) => {
    if (i === index) {
      el[key] = value
    }
    return el
  })
  setValue()
}
// 移除
const remove = (index: number) => {
  arr.value = arr.value.filter((el, i) => {
    return i !== index
  })
  setValue()
}
const setValue = () => {
  emits('update:modelValue', arr.value)
  emits('change', arr.value)
}
// 打开更多配置
const openMoreConfig = () => {
  emits('open')
}
watch(props, () => {
  arr.value = props.modelValue
})
onMounted(() => {
  arr.value = props.modelValue
})
</script>

<style lang="scss" scoped>
.table-column-group {
  width: 100%;
  .table-column-item {
    display: flex;
    align-items: center;
    margin-bottom: 20px;

    i {
      cursor: move;
      margin-right: 5px;
    }
    .value {
      width: 200px;
      margin-right: 5px;
    }
  }

  .btn-group {
    display: flex;
    justify-content: space-between;
  }
}
</style>
